home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / dev / e / doomwad.lha / modules / doomwad.e next >
Text File  |  1998-03-15  |  10KB  |  344 lines

  1. /*
  2. ** DOOMWAD.M
  3. **
  4. ** ©1998 Peter Gordon (the.moosuck@borghome.demon.co.uk)
  5. **
  6. ** Use, improve, abuse. The only restriction is you must credit me for
  7. ** any usage.
  8. **
  9. */
  10.  
  11. OPT MODULE
  12.  
  13. MODULE 'exec/memory', 'dos/dos'
  14.  
  15. /* Names of all the "THINGS" */
  16.  
  17. EXPORT CONST TG_PLAYERSTART1=1,
  18.              TG_PLAYERSTART2=2,
  19.              TG_PLAYERSTART3=3,
  20.              TG_PLAYERSTART4=4,
  21.              TG_DEATHMSTART=11,
  22.              TG_TELEPORTLAND=14,
  23.              TG_PISTOLZOMBIE=$BBC,
  24.              TG_WOLFENSTEINGUY=$54,
  25.              TG_SERGEANT=$9,
  26.              TG_CHAINGUNNER=$41,
  27.              TG_IMP=$BB9,
  28.              TG_DEMON=$BBA,
  29.              TG_SPECTRE=$3A,
  30.              TG_FLYSKULL=$BBE,
  31.              TG_CACODEMON=$BBD,
  32.              TG_GREYBARON=$45,
  33.              TG_HELLBARON=$BBB,
  34.              TG_ARACHNOTRON=$44,
  35.              TG_PAINBLOKE=$47,
  36.              TG_SKELETON=$42,
  37.              TG_MANCUBUS=$43,
  38.              TG_ARCHVILE=$40,
  39.              TG_SPIDERMIND=$7,
  40.              TG_CYBERDEAMON=$10,
  41.              TG_BOSSBRAIN=$58,
  42.              TG_BOSSSHOOTER=$59,
  43.              TG_SPAWNSPOT=$57,
  44.              TG_CHAINSAW=$7D5,
  45.              TG_SHOTGUN=$7D1,
  46.              TG_DOUBLESHOT=$52,
  47.              TG_CHAINGUN=$7D2,
  48.              TG_ROCKETLAUNCHER=$7D3,
  49.              TG_PLASMAGUN=$7D4,
  50.              TG_BFG9000=$7D6,
  51.              TG_AMMOCLIP=$7D7,
  52.              TG_SHELLS=$7D8,
  53.              TG_ROCKET=$7DA,
  54.              TG_CELL=$7FF,
  55.              TG_AMMOBOX=$800,
  56.              TG_SHELLBOX=$801,
  57.              TG_ROCKETBOX=$7FE,
  58.              TG_CELLPACK=$11,
  59.              TG_BACKPACK=$8,
  60.              TG_STIMPACK=$7DB,
  61.              TG_MEDIKIT=$7DC,
  62.              TG_HEALTHPOTION=$7DE,
  63.              TG_ARMOUR=$7DF,
  64.              TG_GREENARMOUR=$7E2,
  65.              TG_BLUEARMOUR=$7E3,
  66.              TG_MEGASPHERE=$53,
  67.              TG_SOULSPHERE=$7DD,
  68.              TG_INVULN=$7E6,
  69.              TG_BESERK=$7E7,
  70.              TG_SUIT=$7E9,
  71.              TG_COMPUMAP=$7EA,
  72.              TG_GOGGLES=$7FD,
  73.              TG_BLUECARD=$5,
  74.              TG_BLUESKULLCARD=$28,
  75.              TG_REDCARD=$D,
  76.              TG_REDSKULLCARD=$26,
  77.              TG_YELLOWCARD=$6,
  78.              TG_YELLOWSKULLCARD=$27,
  79.              TG_BARREL=$7F3,
  80.              TG_CMDRKEEN=$48,
  81.              TG_TECHPILLAR=$30,
  82.              TG_GREENPILLAR=$1E,
  83.              TG_REDPILLAR=$20,
  84.              TG_SGREENPILLAR=$1F,
  85.              TG_HEARTPILLAR=$24,
  86.              TG_SREDPILLAR=$21,
  87.              TG_SKULLPILLAR=$25,
  88.              TG_STALAGMITE=$2F,
  89.              TG_BURNTREE=$2B,
  90.              TG_BIGTREE=$36,
  91.              TG_FLOORLAMP=$7EC,
  92.              TG_TALLLAMP=$55,
  93.              TG_SHORTLAMP=$56,
  94.              TG_CANDLE=$22,
  95.              TG_CANDELABRA=$23,
  96.              TG_TBLUEFSTICK=$2C,
  97.              TG_TGREENFSTICK=$2D,
  98.              TG_TREDFSTICK=$2E,
  99.              TG_SBLUEFSTICK=$37,
  100.              TG_SGREENFSTICK=$38,
  101.              TG_SREDFSTICK=$39,
  102.              TG_BURNINGBARREL=$46,
  103.              TG_EVILEYE=$29,
  104.              TG_FLOATSKULL=$2A,
  105.              TG_HANGTWITCH1=$31,
  106.              TG_HANGTWITCH2=$3F,
  107.              TG_HANGARMS1=$32,
  108.              TG_HANGARMS2=$3B,
  109.              TG_HANGLEGS1=$34,
  110.              TG_HANGLEGS2=$3C,
  111.              TG_HANGPEG1=$33,
  112.              TG_HANGPEG2=$3D,
  113.              TG_HANGLEG1=$35,
  114.              TG_HANGLEG2=$3E,
  115.              TG_HANGGUT1=$49,
  116.              TG_HANGGUT2=$4A,
  117.              TG_HANGTORSO1=$4B,
  118.              TG_HANGTORSO2=$4C,
  119.              TG_HANGTORSO3=$4D,
  120.              TG_HANGTORSO4=$4E,
  121.              TG_IMPALED=$19,
  122.              TG_IMPALETWITCH=$1A,
  123.              TG_SKULLPOLE=$1B,
  124.              TG_SKULLKEBAB=$28,
  125.              TG_SKULLCANDLES=$1D,
  126.              TG_PLAYERSPLAT1=$A,
  127.              TG_PLAYERSPLAT2=$C,
  128.              TG_BLOODPOOL1=$18,
  129.              TG_BLOODPOOL2=$4F,
  130.              TG_BLOODPOOL3=$50,
  131.              TG_BRAINPOOL=$51,
  132.              TG_DEADPLAYER=$F,
  133.              TG_DEADZOMBIE=$12,
  134.              TG_DEADSERGEANT=$13,
  135.              TG_DEADIMP=$14,
  136.              TG_DEADDEMON=$15,
  137.              TG_DEADCACODEMON=$16,
  138.              TG_DEADFLYSKULL=$17
  139.  
  140. /* Handle for an open .WAD file */
  141. EXPORT OBJECT wadhandle
  142.   dosh,     -> AmigaDOS handle
  143.   iwad,     -> True if wad is an IWAD, False if its a PWAD
  144.   numlumps, -> Number of lumps in the wad
  145.   dirstrt   -> Offset to the start of the directory
  146. ENDOBJECT
  147.  
  148. /* An entry in the WAD directory */
  149. EXPORT OBJECT dirblock
  150.   offset,   -> Offset to seek to when reading lump
  151.   size,     -> Size of lump
  152.   name[8]:ARRAY OF CHAR -> Name of lump
  153. ENDOBJECT 
  154.  
  155. /* readthings() decodes the THINGS lump into a big linked list of these */
  156. EXPORT OBJECT thing
  157.   prevthing:PTR TO thing,
  158.   nextthing:PTR TO thing,
  159.   x:INT,
  160.   y:INT,
  161.   angle:INT,
  162.   type:INT,
  163.   options:INT
  164. ENDOBJECT
  165.  
  166.  
  167. /* Opens a .WAD file. Returns pointer to wadhandle, or NIL for failure */
  168. EXPORT PROC openwad(name)
  169.   DEF h=0,wh=0:PTR TO wadhandle, tst
  170.   
  171.   -> Allocate memort for wadhandle
  172.   IF(wh:=NewM(SIZEOF wadhandle,MEMF_ANY+MEMF_CLEAR))
  173.   
  174.     -> Open file
  175.     IF(h:=Open(name,OLDFILE))
  176.       
  177.       -> Put DOS handle into wadhandle structure
  178.       wh.dosh:=h
  179.       
  180.       -> Read in first four bytes to check it really is a WAD
  181.       Read(h,{tst},4)
  182.       IF(tst="IWAD")
  183.         -> Its an IWAD
  184.         wh.iwad:=TRUE
  185.       ELSEIF(tst="PWAD")
  186.         -> Its a PWAD
  187.         wh.iwad:=FALSE
  188.       ELSE
  189.         -> Its not a WAD
  190.         Close(wh.dosh)
  191.         h:=0
  192.         Dispose(wh)
  193.         wh:=0
  194.         RETURN 0
  195.       ENDIF
  196.       -> Read the number of lumps
  197.       Read(h,{tst},4)
  198.       -> Convert to motorola and store in numlumps
  199.       wh.numlumps:=motolong(tst)
  200.       -> Read start of WAD directory
  201.       Read(h,{tst},4)
  202.       -> Convert to motorola and store in dirstrt
  203.       wh.dirstrt:=motolong(tst)
  204.     ELSE
  205.       Dispose(wh)
  206.       wh:=0
  207.       RETURN 0
  208.     ENDIF
  209.   ENDIF
  210. ENDPROC wh
  211.  
  212. -> Closes and open wad
  213. EXPORT PROC closewad(wh:PTR TO wadhandle)
  214.   IF(wh)
  215.     Close(wh.dosh)
  216.     Dispose(wh)
  217.   ENDIF
  218. ENDPROC
  219.  
  220. -> Frees up a whole thinglist
  221. EXPORT PROC freethings(thinglist:PTR TO thing)
  222.   DEF cthing:PTR TO thing
  223.   WHILE(thinglist>0)
  224.     cthing:=thinglist.nextthing
  225.     Dispose(thinglist)
  226.     thinglist:=cthing
  227.   ENDWHILE
  228. ENDPROC
  229.  
  230. -> This routine reads the whole THINGS lump from a level into a big linked
  231. -> list
  232. EXPORT PROC readthings(levelname,wh:PTR TO wadhandle)
  233.   DEF c,d,m=0,dirblock:dirblock,thinglist:PTR TO thing,cthing:PTR TO thing
  234.   
  235.   -> Looks for the level you require
  236.   IF(c:=findentry(levelname,wh,dirblock)=0) THEN RETURN 0
  237.   
  238.   -> Scan for a things lump
  239.   WHILE(c<wh.numlumps)
  240.     INC c
  241.     
  242.     -> Get entry from WAD dir
  243.     readentry(c*16,wh,dirblock)
  244.     
  245.     -> Is it the THINGS lump?
  246.     IF(StrCmp(dirblock.name,'THINGS'))
  247.     
  248.       -> Yeah! So seek to the start of the THINGS lump
  249.       Seek(wh.dosh,dirblock.offset,OFFSET_BEGINNING)
  250.       d:=0
  251.       
  252.       -> Allocate a "thing" object
  253.       IF(thinglist:=NewM(SIZEOF thing,MEMF_ANY+MEMF_CLEAR))
  254.       
  255.         -> Point to the first "thing" in the list
  256.         cthing:=thinglist
  257.         WHILE(d<dirblock.size)
  258.         
  259.           -> Read, translate to motorola, and fill in the current
  260.           -> thing object
  261.           Read(wh.dosh,{m}+2,2)
  262.           cthing.x:=motoword(m)
  263.           Read(wh.dosh,{m}+2,2)
  264.           cthing.y:=motoword(m)
  265.           Read(wh.dosh,{m}+2,2)
  266.           cthing.angle:=motoword(m)
  267.           Read(wh.dosh,{m}+2,2)
  268.           cthing.type:=motoword(m)
  269.           Read(wh.dosh,{m}+2,2)
  270.           cthing.options:=motoword(m)
  271.           
  272.           -> Point to next thing
  273.           d:=d+10
  274.           
  275.           -> If we're still in the thing lump...
  276.           IF(d<dirblock.size)
  277.             -> ... allocate another thing object
  278.             IF(m:=NewM(SIZEOF thing,MEMF_ANY+MEMF_CLEAR))
  279.  
  280.               -> And make the previous thing object point to the current
  281.               -> one, and the current one point to the last one.
  282.               cthing.nextthing:=m
  283.               cthing.nextthing.prevthing:=cthing
  284.               cthing:=m
  285.             ELSE
  286.             
  287.               -> Not enough memory, so free any we've already allocated
  288.               -> and return failure
  289.               freethings(thinglist)
  290.               RETURN 0
  291.             ENDIF
  292.           ENDIF
  293.         ENDWHILE
  294.         RETURN thinglist
  295.       ELSE
  296.         RETURN 0
  297.       ENDIF
  298.     ENDIF
  299.     -> Eek! No things!
  300.     IF(StrCmp(dirblock.name,'MAP',3)) THEN RETURN 0
  301.     IF(StrCmp(dirblock.name,'LINEDEFS')=0) AND (StrCmp(dirblock.name,'SIDEDEFS')=0) AND (StrCmp(dirblock.name,'VERTEXES')=0) AND (StrCmp(dirblock.name,'SEGS')=0) AND (StrCmp(dirblock.name,'SSECTORS')=0) AND (StrCmp(dirblock.name,'NODES')=0) AND (StrCmp(dirblock.name,'SECTORS')=0) AND (StrCmp(dirblock.name,'REJECT')=0) AND (StrCmp(dirblock.name,'BLOCKMAP')=0) THEN RETURN 0
  302.   ENDWHILE
  303. ENDPROC 0
  304.  
  305. -> Scans the WAD dir for a specific lump
  306. EXPORT PROC findentry(entryname,wh:PTR TO wadhandle,dirblock:PTR TO dirblock)
  307.   DEF c=0
  308.   WHILE(c<wh.numlumps)
  309.     readentry(c*16,wh,dirblock)
  310.     IF(StrCmp(dirblock.name,entryname)) THEN RETURN -1,c
  311.     INC c
  312.   ENDWHILE
  313. ENDPROC 0,0
  314.  
  315. -> Reads a directory entry into a dirblock structure
  316. EXPORT PROC readentry(offset,wh:PTR TO wadhandle,dirblock:PTR TO dirblock)
  317.   DEF m
  318.   IF(Seek(wh.dosh,(wh.dirstrt+offset),OFFSET_BEGINNING)<>-1)
  319.     Read(wh.dosh,{m},4)
  320.     dirblock.offset:=motolong(m)
  321.     Read(wh.dosh,{m},4)
  322.     dirblock.size:=motolong(m)
  323.     Read(wh.dosh,dirblock+8,8)
  324.   ENDIF
  325. ENDPROC
  326.  
  327. -> Converts an intel word into a motorola word.
  328. -> It actually would convert a motorola word into an Intel one as well :)
  329. EXPORT PROC motoword(intel:PTR TO INT)
  330.   DEF tmp
  331.   tmp:=Char({intel}+3)
  332.   PutChar({intel}+3,Char({intel}+2))
  333.   PutChar({intel}+2,tmp)
  334. ENDPROC intel
  335.  
  336. -> Same as motoword() but for longs
  337. EXPORT PROC motolong(intel)
  338.   DEF tmp1,tmp2
  339.   tmp1:=motoword(Int({intel}))
  340.   tmp2:=motoword(Int({intel}+2))
  341.   PutInt({intel},tmp2)
  342.   PutInt({intel}+2,tmp1)
  343. ENDPROC intel
  344.